<template>
    <div class="dept-tree-selector">
        <el-select v-model="selectedDeptId" :placeholder="placeholder" filterable class="dept-select"
            @change="handleChange">
            <el-option v-for="dept in deptTreeData" :key="dept.id" :label="dept.label" :value="dept.id">
                <span class="dept-option">
                    <el-icon>
                        <Folder />
                    </el-icon>
                    <span>{{ dept.label }}</span>
                </span>
            </el-option>
        </el-select>
    </div>
</template>

<script setup lang="ts">
import { ref, reactive, watch, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import { Folder } from '@element-plus/icons-vue'
import { getDepartmentTree } from '@/api/department'

// 定义组件Props
const props = defineProps({
    modelValue: {
        type: Number,
        default: 0
    },
    placeholder: {
        type: String,
        default: '请选择部门'
    }
})

// 定义事件
const emit = defineEmits(['update:modelValue', 'change'])

interface TreeNode {
    id: number;
    label: string;
    children?: TreeNode[];
    originalData?: any;
}

// 部门树数据
const deptTreeData = ref<TreeNode[]>([])

// 已选中的部门ID
const selectedDeptId = ref<number>(props.modelValue)

// 监听props.modelValue变化
watch(() => props.modelValue, (newValue) => {
    selectedDeptId.value = newValue as number
}, { immediate: true })

// 监听选中值变化，触发v-model更新
watch(() => selectedDeptId.value, (newValue) => {
    emit('update:modelValue', newValue)
})

// 处理选择变化
const handleChange = (value: number) => {
    emit('change', value);
}

// 递归处理部门树结构
const processDepartments = (departments: any[]): TreeNode[] => {
    if (!departments || !departments.length) return [];

    return departments.map(dept => {
        const node: TreeNode = {
            id: dept.value, // 使用value作为ID
            label: dept.label || '未命名部门',
            originalData: dept
        };

        // 如果有子部门，递归处理
        if (dept.children && dept.children.length) {
            node.children = processDepartments(dept.children);
        }

        return node;
    });
};

// 扁平化部门树，将所有部门放在一级
const flattenDepartmentTree = (departments: TreeNode[]): TreeNode[] => {
    let result: TreeNode[] = [];

    departments.forEach(dept => {
        // 添加当前部门
        result.push({
            id: dept.id,
            label: dept.label,
            originalData: dept.originalData
        });

        // 如果有子部门，递归处理
        if (dept.children && dept.children.length) {
            const childDepts = flattenDepartmentTree(dept.children);
            // 子部门名称前添加缩进，表示层级关系
            childDepts.forEach(child => {
                child.label = `　├ ${child.label}`;
            });
            result = [...result, ...childDepts];
        }
    });

    return result;
};

// 获取并转换部门树数据
const fetchDepartmentTree = async () => {
    try {
        const apiResponse = await getDepartmentTree();

        // 保存完整的API响应数据，使用类型断言避免TypeScript错误
        const data = (apiResponse as any)?.Data || [];
        console.log('部门树API返回数据:', data);

        // 处理部门树结构
        const treeNodes = processDepartments(data);

        // 扁平化处理，将树形结构转为列表
        const flattenedNodes = flattenDepartmentTree(treeNodes);

        // 添加一个"根部门"选项
        const rootNode: TreeNode = {
            id: 0,
            label: '根部门'
        };

        // 赋值结果，将根部门放在最前面
        deptTreeData.value = [rootNode, ...flattenedNodes];
        console.log('部门树数据加载完成', deptTreeData.value.length);
    } catch (error) {
        console.error('获取部门树失败:', error);
        deptTreeData.value = [{
            id: 0,
            label: '根部门'
        }];
    }
};

// 检查是否需要加载部门树数据
const checkAndLoadDepartmentTree = () => {
    if (deptTreeData.value.length <= 1 && props.modelValue) {
        fetchDepartmentTree();
    }
};

// 组件挂载时获取数据
onMounted(() => {
    fetchDepartmentTree();
    // 在组件挂载后检查是否需要加载部门数据
    checkAndLoadDepartmentTree();
})
</script>

<style scoped>
.dept-tree-selector {
    width: 100%;
}

.dept-select {
    width: 100%;
}

.dept-option {
    display: flex;
    align-items: center;
    font-size: 14px;
}

.dept-option .el-icon {
    margin-right: 6px;
    color: #909399;
}
</style>